home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
tex
/
rpsort.zip
/
RPTAB.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1991-08-16
|
21KB
|
533 lines
{$A+,B-,D-,E-,F-,G-,I-,L-,N-,O-,R-,S-,V-,X-}
program RPTab;
{-------------------------Syntax Of RPTAB ----------------------------------}
{ RPTAB input-filespec output-filespec [tabstop...]
The input is a file containing tabs to be expanded. The contents of the
output file will be the same except that all tabs will have been expanded
to the appropriate number of spaces.
If you don't specify any tab stops, the default tab stops are at columns
1, 9, 17, 25, 33 and so on at intervals of 8 columns. If you specify tab
stops, they must be a sequence of integers each greater than the preceding
one. The first tab stop is always at column 1 and you need not specify it.
RPTAB follows the rule that the interval between the last two tab stops,
you specify, implies subsequent tab stops at the same interval. For
example, the command:
RPTAB MYTABS.DAT MYSPACES.DAT 6 15 27
tells RPTAB that the tab stops are at columns 1, 6, 15, 27, 39, 51 and etc.
The interval of 12 between 15 and 27 is propagated to subsequent tab stops.}
{-------------- Const, Type and Variable Declarations ---------------------}
const
BuffSize = 32768;
type
TabArray = array[1..50] of Word;
DataArray = array[0..BuffSize-1] of Char;
DataPtr = ^DataArray;
var
Tab : TabArray; {This array holds the tab stops to be used.}
TabCt : Byte; {Number of tab stops specified or implied.}
IpFile, OpFile : file;
IpPtr, OpPtr : DataPtr; {Pointers to buffers for input and output files.}
IpNext, OpNext : Word; {Offset of next byte in input and output buffers.}
IpRead, OpWritten : Word; {Actual bytes read/written by each I/O request.}
MoreData : Boolean; {Set to False at end of input file.}
Column : Word; {Current column in current output line.}
FillCt : Word; {Spaces required to fill out tab.}
{----------------------- function GotFiles ---------------------------------}
{Function GotFiles returns the value True if it successfully opens both the
input and output files. Otherwise it returns False.}
function GotFiles(var IpFile, OpFile : file) : Boolean;
var
HoldIOResult : Word;
begin
{Must specify two or more parameters including input and output files.}
if ParamCount < 2 then
begin
Writeln('Must specify an input file and an output file.');
GotFiles := False;
exit
end;
{Setting FileMode=0 tells the Reset procedure to open file as read only.}
FileMode := 0;
Assign(IpFile, ParamStr(1));
Assign(OpFile, ParamStr(2));
{If Reset fails, display error message and set function result to False.}
Reset(IpFile, 1);
HoldIOResult := IOResult;
if HoldIOResult > 0 then
begin
case HoldIOResult of
2 : Writeln('Input file not found: ', ParamStr(1));
3 : Writeln('Invalid input file spec: ', ParamStr(1));
else Writeln('Unable to open input file: ', ParamStr(1));
end;
GotFiles := False;
Exit
end;
{If Rewrite fails, display error message and set function result to False.}
Rewrite(OpFile, 1);
HoldIOResult := IOResult;
if HoldIOResult > 0 then
begin
case HoldIOResult of
3 : Writeln('Invalid output file spec: ', ParamStr(2));
else Writeln('Unable to open output file: ', ParamStr(2));
end;
GotFiles := False;
Exit
end;
{If both files opened successfully, return function result True.}
GotFiles := True
end;
{------------------- procedure CloseDelete --------------------------------}
procedure CloseDelete;
begin
Close(IpFile);
Close(OpFile);
Erase(OpFile)
end;
{--------------------- function GotTabs -----------------------------------}
{Function GotTabs returns the value True if it successfully creates the
array of tab stops. Otherwise it returns False.}
function GotTabs(var Tab : TabArray; var TabCt : Byte) : Boolean;
var
Temp : LongInt;
Code : Integer;
Start, I : Byte;
begin
{The default tab stops are at columns 1, 9, 17, 25 (and so on at intervals
of eight columns). Internally, RPTab represents these as 0, 8, 16, 24 etc.
Since the interval between the last two explicit tab stops is propagated to
subsequent tab stops, EXPTABS sets two tab stops at columns 0 and 8 in the
Tab array and sets TabCT = 2. It also sets GotTabs to True on the
assumption that tab stops will be OK.}
Tab[1] := 0;
Tab[2] := 8;
TabCt := 2;
GotTabs := True;
{If ParamCount is 2 then only files were specified and no tab stops. Thus,
RPTAB sticks with the default tab stops set above.}
if ParamCount = 2 then Exit;
{If the first specified tab stop (ParamStr(3)) is a valid integer and equals
1, then having already set the first tab stop at 1, we will start with the
4th parameter.}
Val(ParamStr(3), Temp, Code);
if (Code = 0) and (Temp = 1) then
if ParamCount > 3
then Start := 4
else Exit
else Start := 3;
TabCt := ParamCount - Start + 2;
{Get each tab stop in turn. Check that it is an integer between 1 and
65535 and that it is greater than the previous tab stop. If not, display
an error message and return with GotTabs = False.}
{If a tab stop is OK, decrement it by 1 and store it in the corresponding
Tab array bucket. I decrement it because internally I count columns
starting with zero while externally I count them starting with one.}
for I := 2 to TabCt do
begin
Val(ParamStr(Start + I - 2), Temp, Code);
if (Code <> 0) or (Temp < 1) or (Temp > 65535) then
begin
Writeln('Tab stop must be integer between 1 and 65535: ',
ParamStr(Start + I - 2));
GotTabs := False;
CloseDelete;
Exit
end;
if Tab[I - 1] >= (Temp - 1) then
begin
Writeln('Tab stop at ', Temp, ' must exceed the ',
'previous tab stop at ', Tab[I - 1]+1, '.');
GotTabs := False;
CloseDelete;
Exit
end;
Tab[I] := Temp - 1
end
end;
{-------------------- function ReadOk ------------------------------------}
{Function ReadOk returns the value True if it successfully reads from the
input file. Otherwise it displays an error message and returns False.}
function ReadOK(var IpFile : file; var Buff : DataArray; BuffSize : Word;
var IpRead : Word) : Boolean;
var
HoldIOResult : Word;
begin
BlockRead(IpFile, Buff, BuffSize, IpRead);
HoldIOResult := IOResult;
if HoldIOResult <> 0 then
begin
Writeln('Error reading input file.');
ReadOK := False;
CloseDelete
end
else ReadOK := True
end;
{---------------------- function WriteOK ----------------------------------}
{Function WriteOk returns the value True if it successfully writes to the
output file. Otherwise it displays an error message and returns False.}
function WriteOK(var OpFile : file; var Buff : DataArray; WriteLen : Word;
var OpWritten : Word) : Boolean;
var
HoldIOResult : Word;
begin
WriteOK := True;
BlockWrite(OpFile, Buff, WriteLen, OpWritten);
HoldIOResult := IOResult;
if HoldIOResult <> 0 then
begin
Writeln('Error writing output file.');
CloseDelete;
WriteOk := False
end;
if OpWritten <> WriteLen then
begin
Writeln('Ran out of space on disk writing output file.');
CloseDelete;
WriteOk := False
end;
end;
{---------------